package com.gxar.file.server.base.reference;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gxar.file.server.base.common.constant.UserConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 用户远程调用
 *
 * @author linsy
 * @version 1.0
 * @created 2023/6/27 14:54
 */
@Service
@Slf4j
public class UserReference {

    /**
     * 用户信息服务
     *
     * @param userId 用户ID
     * @param token  token
     * @return
     */
    public JSONObject profileService(String userId, String token) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new HashMap<>();
        paramJson.put("service", UserConstant.PROFILE_SERVICE);
        paramJson.put("user_id", userId);
        paramJson.put("token", token);
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            return JSON.parseObject(JSON.toJSONString(userServiceObject));
        }
        return null;
    }

    /**
     * 校验用户登录状态
     *
     * @param userId 用户ID
     * @param token  token
     * @return 响应
     */
    public JSONObject checkSessionService(String userId, String token) {
        // 构建范化调用服务
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, String> params = new HashMap<>();
        Map<String, String> paramJson = new HashMap<>();
        paramJson.put("service", UserConstant.CHECK_SESSION_SERVICE);
        paramJson.put("user_id", userId);
        paramJson.put("token", token);
        params.put("params", JSON.toJSONString(paramJson));
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        Object userServiceObject = genericService.$invoke("dubboRpc", paramTypes, paramValues);
        if (Objects.nonNull(userServiceObject)) {
            return JSON.parseObject(JSON.toJSONString(userServiceObject));
        }
        return null;
    }

    /**
     * 构建范化调用服务
     *
     * @return 范化调用服务
     */
    private GenericService buildGenericService() {
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        // 弱类型接口名
        reference.setApplication(new ApplicationConfig("user-provider"));
        //接口类全限定类名
        reference.setInterface("com.gxar.api.UserService");
        reference.setCheck(false);
        //接口版本号
        reference.setVersion("1.0.0");
        // 声明为泛化接口
        reference.setGeneric(true);
        reference.setSerialization("fastjson");
        // 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用
        ReferenceConfigCache cache = ReferenceConfigCache.getCache();
        return cache.get(reference);
    }
}
